package com.yuzhihao.writejvm.code.w;

import com.yuzhihao.writejvm.clazz.ClassInfo;
import com.yuzhihao.writejvm.code.Operation;
import com.yuzhihao.writejvm.code.StackFrame;
import com.yuzhihao.writejvm.code.i.Iinc;
import com.yuzhihao.writejvm.format.FormsEnum;
import com.yuzhihao.writejvm.format.NewarrayTypeEnum;
import com.yuzhihao.writejvm.format.PrintFormat;
import com.yuzhihao.writejvm.read.Parse;
import com.yuzhihao.writejvm.read.Parses;
import com.yuzhihao.writejvm.read.ReadClassFileFatory;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.log4j.Log4j2;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * wide
 * @author yzh
 * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.wide">jvmdoc</a>
 * @since 2021年12月16日15:32:03
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Log4j2
public class Wide extends Operation implements Parses {

    private FormsEnum fe = FormsEnum.wide;

    private ClassInfo ci;

    private int indexbyte1;
    private int indexbyte2;

    private int lindex;

    private int constbyte1;
    private int constbyte2;

    private int constb;

    private Operation operation;

    private NewarrayTypeEnum nt;

    @Override
    public StackFrame exec(StackFrame frame) {

        return frame;
    }

    

    @Override
    public String print(String print) {
        return print + PrintFormat.EMPTY + super.index+PrintFormat.COLON+PrintFormat.EMPTY+fe.name()+System.lineSeparator();
    }

    @Override
    public int parse(DataInputStream dis, ClassInfo ci) {
        int result = 2;
        this.setCi(ci);
        try {
            this.indexbyte1 = Parse.byteToInt(1, dis);
            this.indexbyte1 = Parse.byteToInt(1, dis);
            this.lindex = (indexbyte1 << 8) | indexbyte2;
            int tag = Parse.byteToInt(1, dis);
            result +=1;
            this.operation = ReadClassFileFatory.frame_instance(tag);
            if(operation instanceof Iinc){
                this.constbyte1 = Parse.byteToInt(1, dis);
                this.constbyte2 = Parse.byteToInt(1, dis);
                this.constb = (constbyte1 << 8) | constbyte2;
                result += 2;
            }
        } catch (IOException e) {
            log.error(e);
        }

        return result;
    }

}
